// 类型断言（Type Assertion）可以用来手动指定一个值的类型
// 值 as 类型       <类型>值

// 当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候，我们只能访问此联合类型的所有类型中共有的属性或方法：
// interface Cat {
//     name: string;
//     run(): void;
// }
// interface Fish {
//     name: string;
//     swim(): void;
// }
// function getName(animal: Cat | Fish) {
//     return animal.name;
// }


// interface Cat {
//     name: string;
//     run(): void;
// }
// interface Fish {
//     name: string;
//     swim(): void;
// }
// function isFish(animal: Cat | Fish) {
//     if (typeof (animal as Fish).swim === 'function') {
//         return true;
//     }
//     return false;
// }
// console.log(isFish({name: 'cat', swim: ()=>1+2}));

// 错误 el:
// interface Cat {
//     name: string;
//     run(): void;
// }
// interface Fish {
//     name: string;
//     swim(): void;
// }

// function swim(animal: Cat | Fish) {
//     (animal as Fish).swim();
// }

// const tom: Cat = {
//     name: 'Tom',
//     run() { console.log('run') }
// };
// swim(tom);



// 将一个父类断言为更加具体的子类
class ApiError extends Error {
    code: number = 0;
}
class HttpError extends Error {
    statusCode: number = 200;
}

function isApiError(error: Error) {
    if (error instanceof ApiError) {
        return true;
    }
    return false;
}



// 类型断言 泛型
function getCacheData<T>(key: string): T {
    return (window as any).cache[key];
}
interface Cat {
    name: string;
    run(): void;
}
const tom = getCacheData<Cat>('tom');
tom.run();